home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS09.ADF / MicroEMACS / mouse.c < prev    next >
C/C++ Source or Header  |  1986-05-22  |  13KB  |  505 lines

  1. /*
  2.  *  This file implements memacs support for the Amiga mouse.
  3.  *  Author:  Andy Poggio
  4.  */
  5.  
  6. #include <exec/types.h>
  7. #include <exec/exec.h>
  8. #include <intuition/intuition.h>
  9. #include <devices/console.h>
  10. #include <stdio.h>
  11. #include "ed.h"
  12.  
  13. #define NL 0
  14.  
  15. extern struct Window *Window;
  16.  
  17. /* Font sizes */
  18.  
  19. #define FONT_X 8
  20. #define FONT_Y 8
  21.  
  22. /* Button Codes */
  23.  
  24. #define LEFT_BUTTON 1
  25. #define RIGHT_BUTTON 2
  26.  
  27. /* Copies of this structure will get "stamped" into many more */
  28. /* Allocated later */
  29. struct IntuiText generic = {
  30.   0, 1,                        /* Bluepen, Whitepen */
  31.   JAM2, 5,                     /* mode,  LeftEdge */
  32.   0, NL,                       /* Top (to be filled later), Font */
  33.   NL,                          /* Name (to be filled later) */
  34.   NL                           /* Next one */
  35. };
  36.  
  37. #define NUM_MENUS 4
  38.  
  39. /* Menu numbers */
  40. #define PRO_MENU 0
  41. #define REG_MENU 1
  42. #define COM_MENU 2
  43. #define OPT_MENU 3
  44.  
  45. /* Menu Widths */
  46. #define COM_WIDTH  72
  47.  
  48. #define ITEM_WIDTH 112 
  49.  
  50. /* All items in these menus have the following flags set */
  51. #define BLACK_FILL  ITEMTEXT | ITEMENABLED | HIGHCOMP
  52.  
  53.                             /** FILE MENU ITEMS  **/
  54. #define NUM_PRO_ITEMS   6
  55. #define NUM_REG_ITEMS    4
  56. #define NUM_COM_ITEMS   7
  57. #define NUM_OPT_ITEMS    6
  58.  
  59. #define NEWBUF_ITEM     0
  60. #define OPEN_ITEM       1
  61. #define SAVE_ITEM       2
  62. #define SAVEAS_ITEM     3
  63. #define QUITNSAVE_ITEM  4
  64. #define QUIT_ITEM       5
  65.  
  66. #define KILL_ITEM       0
  67. #define COPY_ITEM    1
  68. #define UNKILL_ITEM     2
  69. #define FILEYANK_ITEM   3
  70.  
  71. #define NOOP_ITEM       0
  72. #define SEARCH_ITEM    1
  73. #define QUERY_ITEM      2
  74. #define STARTM_ITEM    3
  75. #define ENDM_ITEM    4
  76. #define EXECM_ITEM    5
  77. #define NEW_ITEM        6
  78.  
  79. #define TWO_ITEM        0
  80. #define ONE_ITEM        1
  81. #define AUTOIND_ITEM    2
  82. #define WORDRAP_ITEM    3
  83. #define LEFTMAR_ITEM    4
  84. #define RIGHTMAR_ITEM    5
  85.  
  86. struct MenuItem  pro_items[NUM_PRO_ITEMS];
  87. struct IntuiText pro_names[NUM_PRO_ITEMS];
  88. struct MenuItem  reg_items[NUM_REG_ITEMS];
  89. struct IntuiText reg_names[NUM_REG_ITEMS];
  90. struct MenuItem  com_items[NUM_COM_ITEMS];
  91. struct IntuiText com_names[NUM_COM_ITEMS];
  92. struct MenuItem  opt_items[NUM_OPT_ITEMS];
  93. struct IntuiText opt_names[NUM_OPT_ITEMS];
  94.  
  95. char  *promenu_names[] = {
  96.    "New Buffer ",
  97.    "Open       ",
  98.    "Save       ",
  99.    "Save As    ",
  100.    "Quit & Save",
  101.    "Quit       "
  102. };
  103.  
  104. char  *regmenu_names[] = {
  105.    "Cut        ",
  106.    "Copy       ",
  107.    "Paste      ",
  108.    "File Paste "
  109. };
  110.  
  111. char  *commenu_names[] = {
  112.    "No Operaton  ",
  113.    "Search       ",
  114.    "Replace      ",
  115.    "Start Macro  ",
  116.    "End Macro    ",
  117.    "Execute Macro",
  118.    "New CLI      "
  119.    };
  120.  
  121. char  *optmenu_names[] = {
  122.    "Split Window",
  123.    "One Window  ",
  124.    "Auto indent ",
  125.    "Word wrap   ",
  126.    "Left Margin ",
  127.    "Right Margin"
  128.    };
  129.    
  130. struct Menu pmenu = {
  131.    NULL,                /* Pointer to next menu */
  132.    0, 0, COM_WIDTH, 10, /* LeftEdge, TopEdge, Width, Height */
  133.    MENUENABLED,         /* FLAGS */
  134.    "Project",           /* Menu name */
  135.    pro_items            /* First item structure */
  136. };
  137.  
  138. struct Menu rmenu = {
  139.    NULL,                /* Pointer to next menu */
  140.    COM_WIDTH, 0, COM_WIDTH, 10,     /* LeftEdge, TopEdge, Width, Height */
  141.    MENUENABLED,         /* FLAGS */
  142.    "Region",            /* Menu name */
  143.    reg_items            /* First item structure */
  144. };
  145.  
  146. struct Menu cmenu = {
  147.    NULL,                /* Pointer to next menu */
  148.    COM_WIDTH*2, 0, COM_WIDTH, 10,   /* LeftEdge, TopEdge, Width, Height */
  149.    MENUENABLED,         /* FLAGS */
  150.    "Commands",          /* Menu name */
  151.    com_items            /* First item structure */
  152. };
  153.  
  154. struct Menu omenu = {
  155.    NULL,                /* Pointer to next menu */
  156.    COM_WIDTH*3, 0, COM_WIDTH, 10,   /* LeftEdge, TopEdge, Width, Height */
  157.    MENUENABLED,         /* FLAGS */
  158.    " Options",          /* Menu name */
  159.    opt_items            /* First item structure */
  160. };
  161.  
  162. mouse_setup_menu()
  163. {
  164.    mouse_newmenu( &pmenu, promenu_names, pro_items, pro_names,
  165.             NUM_PRO_ITEMS, ITEM_WIDTH, BLACK_FILL);
  166.    mouse_newmenu( &rmenu, regmenu_names, reg_items, reg_names,
  167.             NUM_REG_ITEMS, ITEM_WIDTH, BLACK_FILL);
  168.    mouse_newmenu( &cmenu, commenu_names, com_items, com_names,
  169.             NUM_COM_ITEMS, ITEM_WIDTH, BLACK_FILL);
  170.    mouse_newmenu( &omenu, optmenu_names, opt_items, opt_names,
  171.             NUM_OPT_ITEMS, ITEM_WIDTH, BLACK_FILL);
  172.         
  173.    pmenu.NextMenu = &rmenu;
  174.    rmenu.NextMenu = &cmenu;
  175.    cmenu.NextMenu = &omenu;
  176.  
  177.    reg_items[0].Command = 'X';
  178.    reg_items[1].Command = 'C';
  179.    reg_items[2].Command = 'P';
  180.  
  181.    reg_items[0].Flags |= COMMSEQ;
  182.    reg_items[1].Flags |= COMMSEQ;
  183.    reg_items[2].Flags |= COMMSEQ;
  184.  
  185.    SetMenuStrip(Window, &pmenu);      /* Set up the menu here */
  186. }
  187.  
  188. mouse_clear_menu()
  189. {
  190.    ClearMenuStrip(Window, &cmenu);
  191. }
  192.  
  193. static
  194. do_menu( m, f, n) /* execute a menu command */
  195. {
  196. int menu, item, sub;
  197.  
  198. menu = MENUNUM( m);
  199. item = ITEMNUM( m);
  200. sub = SUBNUM( m);
  201.         
  202. if( kbdmip != NULL)        /* collecting macro */
  203.     {
  204.     if ( menu == COM_MENU && item == ENDM_ITEM )    /* End macro */
  205.         ;
  206.     else
  207.         {
  208.         ctrlg(FALSE, 0);
  209.         return( FALSE );
  210.         }
  211.     }
  212.         
  213. switch( menu)
  214.    {
  215.    case PRO_MENU:
  216.       switch( item)
  217.          {
  218.          case NEWBUF_ITEM:
  219.         usebuffer( f, n);
  220.             break;
  221.          case OPEN_ITEM:
  222.         fileread( f, n);
  223.             break;
  224.          case SAVE_ITEM:
  225.         filesave( f, n);
  226.             break;
  227.          case SAVEAS_ITEM:
  228.         filewrite( f, n);
  229.             break;
  230.          case QUITNSAVE_ITEM:
  231.         quickexit( f, n);
  232.             break;
  233.          case QUIT_ITEM:
  234.             quit( f, n);
  235.             break;
  236.          }
  237.       break;
  238.    case REG_MENU:
  239.       switch( item)
  240.      {
  241.      case COPY_ITEM:
  242.             copyregion( f, n);
  243.             break;
  244.          case KILL_ITEM:
  245.             killregion( f, n);
  246.             break;
  247.          case UNKILL_ITEM:
  248.             yank( f, n);
  249.             break;
  250.      case FILEYANK_ITEM:
  251.         fileyank( f, n);
  252.         break;
  253.      }
  254.       break;
  255.    case COM_MENU:
  256.       switch( item)
  257.          {
  258.      case NOOP_ITEM:
  259.             break;
  260.      case SEARCH_ITEM:
  261.             forwsearch( f, n);
  262.             break;
  263.          case QUERY_ITEM:
  264.             qreplace( f, n);
  265.             break;
  266.      case STARTM_ITEM:
  267.         ctlxlp( f, n);
  268.         break;
  269.      case ENDM_ITEM:
  270.         ctlxrp( f, n);
  271.         break;
  272.      case EXECM_ITEM:
  273.         ctlxe( f, n);
  274.         break;
  275.          case NEW_ITEM:
  276.             spawncli( f, n);
  277.             break;
  278.          }
  279.       break;
  280.    case OPT_MENU:
  281.       switch( item )
  282.          {
  283.          case TWO_ITEM:
  284.             splitwind( f, n);
  285.             break;
  286.          case ONE_ITEM:
  287.             onlywind( f, n);
  288.             break;
  289.      case WORDRAP_ITEM:
  290.         togglewordwrap( f, n);
  291.         break;
  292.      case AUTOIND_ITEM:
  293.         toggleautoindent( f, n);
  294.         break;
  295.      case LEFTMAR_ITEM:
  296.         setfillcol( 0, n);
  297.         break;
  298.      case RIGHTMAR_ITEM:
  299.         setfillcol( 1, n);
  300.         break;
  301.      }
  302.       break;
  303.    default:
  304.       break;
  305.    }
  306. }
  307.  
  308. mouse_handle_event( f, n)
  309. {
  310. register char *s;
  311. int result, c, class, subclass, keycode, qualifiers, x, y, secs, musecs;
  312. char instr[ 88 ];    /* 8 nine digit numbers with separators + 1 */
  313. static int netx, nety;
  314. static int button_now = 0, button_ever = 0;
  315.  
  316. for ( s = instr; (*s++ = ttgetc()) != '|';)
  317.     ;
  318. *s = 0; /* terminate the str */
  319.  
  320. sscanf( instr, "%d;%d;%d;%d;%d;%d;%d;%d|",
  321.         &class, &subclass, &keycode, &qualifiers, &x, &y, &secs, &musecs);
  322.  
  323. switch( class) 
  324.     {
  325.     case 2:                 /* mouse button--only get this for left button */
  326.         if( keycode & 0x80)         /* key up */
  327.         {
  328.             keycode &= ~0x80;       /* clear the up bit */
  329.             button_now &= ~ LEFT_BUTTON;
  330.         }
  331.         else                        /* key down */
  332.         {
  333.             netx = Window->MouseX - Window->BorderLeft; /* save coords */
  334.             nety = Window->MouseY - Window->BorderTop;
  335.             button_now |= LEFT_BUTTON;
  336.             button_ever |= LEFT_BUTTON;
  337.             }
  338.         break;
  339.     case 10:                /* menu selection -- right button up only */
  340.         if( keycode == MENUNULL) 
  341.         {
  342.             netx = Window->MouseX - Window->BorderLeft; /* save coords */
  343.             nety = Window->MouseY - Window->BorderTop;
  344.             button_ever |= RIGHT_BUTTON;
  345.         }
  346.         else                /* made a menu selection */
  347.         {
  348.             button_ever = 0; /* ignore other buttons */
  349.             do_menu( keycode, f, n);
  350.         }
  351.         break;
  352.     }
  353.  
  354. if ( (!button_now) && button_ever )     /* buttons were pushed: interpret */
  355.     {
  356.     switch( button_ever)
  357.         {
  358.         case LEFT_BUTTON:
  359.             mouse_to_xy( netx, nety);
  360.             break;
  361.         case RIGHT_BUTTON:
  362.             mouse_set_mark( netx, nety);
  363.             break;
  364.         case LEFT_BUTTON | RIGHT_BUTTON:
  365.             forwdel( f, n);
  366.             break;
  367.         }
  368.     button_ever = 0;
  369.     }
  370. }
  371.  
  372. mouse_newmenu( menu, item_names,  menu_items, menu_text, num_items,
  373.                       Mwidth, flag)
  374. struct Menu      *menu;           /* Menu structure                       */
  375. char            *item_names[];    /* Pointer to array of item names       */
  376. struct MenuItem  menu_items[];    /* pointer to array of structures       */
  377. struct IntuiText menu_text[];     /* Pointer to array of text structures  */
  378. int               num_items;      /* Number of items                      */
  379. int               Mwidth;         /* Menu Width */
  380. int                 flag;         /* Special Item flag for ALL items */
  381. {
  382.     int i;
  383.     int height = 0;
  384.  
  385.     for (i=0; i< num_items; i++) {
  386.  
  387.           menu_text[i] = generic;              /* stamp generic template */
  388.           menu_text[i].IText = (UBYTE *) item_names[i];  /* mv string ptrs */
  389.           menu_items[i].NextItem = &menu_items[i+1];  /* Lnk to nxt item */
  390.           menu_items[i].TopEdge = 10 * i;            /* Top rect of item */
  391.           menu_items[i].LeftEdge = 0;
  392.           menu_items[i].Height = 8;
  393.           menu_items[i].ItemFill = (APTR)&menu_text[i];
  394.           menu_items[i].Flags = flag;
  395.           menu_items[i].Width = Mwidth;
  396.           menu_items[i].MutualExclude = 0x0000;
  397.           menu_items[i].Command = 0;
  398.           menu_items[i].SubItem = NL;
  399.           menu_items[i].NextSelect = NL;
  400.           height += 10;
  401.     }
  402.     menu_items[num_items-1].NextItem = NULL;
  403.     menu->Height = height;
  404. }
  405.  
  406. static
  407. winddist( w, row, col) /* calc distance of window from this row, col */
  408. WINDOW *w;
  409. {
  410.     int d;
  411.  
  412.     if( row < w->w_toprow) /* above window */
  413.    return( w->w_toprow - row);
  414.     else if( row < (w->w_toprow + w->w_ntrows)) /* within window */
  415.    return( 0);
  416.     else /* below window */
  417.    return( row - (w->w_toprow + w->w_ntrows));
  418. }
  419.  
  420. WINDOW *
  421. mouse_find_wind( row, col) /* find window containing this row, col */
  422. {
  423.     WINDOW *w, *result_w;
  424.     int distance, result_distance;
  425.  
  426.     result_distance = HUGE; /* greater than any real distance */
  427.     for( w = wheadp; w != NULL; w = w->w_wndp) {
  428.    distance = winddist( w, row, col);
  429.    if( distance < result_distance) {
  430.        result_w = w;
  431.        result_distance = distance;
  432.    }
  433.     }
  434.     return( result_w);
  435. }
  436.  
  437. static
  438. get_wintop( this_w) /* return row for top of this window */
  439. WINDOW *this_w;
  440. {
  441.     register WINDOW *w;
  442.     register int row;
  443.  
  444.     row = 0;
  445.     for( w = wheadp; w != this_w; w = w->w_wndp) {
  446.    row += w->w_ntrows +1;
  447.     }
  448.     return( row);
  449. }
  450.  
  451. mouse_to_xy( x, y) /* move point to position at coords x,y */
  452. {
  453.     register LINE   *dlp;
  454.     register int row, col;
  455.     WINDOW *w;
  456.  
  457.     row = y / FONT_Y; /* convert coords to row and col */
  458.     col = x / FONT_X;
  459.  
  460.     w = mouse_find_wind( row, col); /* find the window and make it current */
  461.     curwp = w;
  462.     curbp = curwp->w_bufp;
  463.  
  464.     row -= get_wintop( curwp); /* adjust to row in window */
  465.     if( row >= curwp->w_ntrows) row = curwp->w_ntrows -1;
  466.  
  467.     dlp = curwp->w_linep;
  468.     while (row-- && dlp!=curbp->b_linep) {
  469.                 dlp = lforw(dlp);
  470.     }
  471.     curwp->w_dotp  = dlp;
  472.     curgoal = col; /* aim for this col */
  473.     curwp->w_doto  = getgoal(dlp);
  474. }
  475.  
  476. mouse_set_mark( x, y) /* set mark at mouse cursor */
  477. {
  478.     WINDOW *wp;
  479.     LINE *dlp;
  480.     int offset;
  481.  
  482.     /* save current position */
  483.    wp = curwp;
  484.    dlp = curwp->w_dotp;
  485.    offset = curwp->w_doto;
  486.  
  487.     /* go to cursor position, set mark, and announce */
  488.    mouse_to_xy( x, y);
  489.    update();
  490.    setmark( FALSE, 1);
  491.    update();
  492.  
  493.     /* return to former position */
  494.    curwp = wp;
  495.    curbp = curwp->w_bufp;
  496.    curwp->w_dotp = dlp;
  497.    curwp->w_doto = offset;
  498. }
  499.  
  500. mouse_enable() /* this must be last to keep ctags happy */
  501. {
  502.    ttputs( "\x1b[2;10{");   /* get mouse button and menu events */
  503.    ttflush();
  504. }
  505.